#include "CabeceraListaInvertida.h"

CabeceraListaInvertida::CabeceraListaInvertida() : IHeader(128), lEspacioLibre(1, 0)
{
	// Inicializa el vector de espacio libre con el valor correspondiente a la cabecera como lleno
}

CabeceraListaInvertida::~CabeceraListaInvertida() { }


unsigned int CabeceraListaInvertida::getPosBloqueLibre(){
	// XXX: Se des-activo todo el control de espacio libre
	return -1;

	// Un bloque libre es el que tiene el tamaño de bytes libre igual al tamaño de este bloque
	for (unsigned int i = 0; i < this->lEspacioLibre.size(); ++i){
		if ( static_cast<unsigned int>( this->lEspacioLibre[i] ) == getTamBloque() ) return i;
	}

	// No hay ningun bloque libre, que lo inserte al final
	return -1;
}


void CabeceraListaInvertida::actualizarEspacioBloque(unsigned int pos, char espacioLibre){
	// XXX: Se des-activo todo el control de espacio libre
	return;

	if ( static_cast<unsigned int>( espacioLibre ) < getTamBloque()){
		// Permito fuera del rango de bloques para usar este metodo en las altas
		if (this->lEspacioLibre.size() > pos) {
			// Actualiza un espacio que ya estaba creado
			this->lEspacioLibre[pos] = espacioLibre;

		} else if (this->lEspacioLibre.size() == pos) {
			// Se agrega un bloque nuevo al final
			this->lEspacioLibre.push_back(espacioLibre);

		} else {
			throw std::runtime_error("Se trató de insertar un bloque fuera del espacio disponible");
		}
	}
}


void CabeceraListaInvertida::liberarBloque(const unsigned int pos){
	// XXX: Se des-activo todo el control de espacio libre
	return;

	if (pos < this->lEspacioLibre.size()) this->lEspacioLibre[pos] = getTamBloque();
}


unsigned int CabeceraListaInvertida::getSize() const {
	unsigned int tam = sizeof(unsigned int) + sizeof(this->cantBloques);
	tam += sizeof(char) * this->lEspacioLibre.size();

	return tam;
}


unsigned int CabeceraListaInvertida::serialize(char* &arr){
	this->serInator.reset();

	// Se guarda la cantidad de elementos
	this->serInator.serializar(arr, this->cantBloques);
	this->serInator.serializar(arr, static_cast<unsigned int>(this->lEspacioLibre.size()));

	// XXX: Se des-activo todo el control de espacio libre
	return this->serInator.getBufferSize();

/*
 * No se guarda la estructura de control de espacio libre porque ocupa
 * demasiado espacio y no entra en los bloques del archivo de listas invertidas
*/
	std::vector<char>::const_iterator it;
	for (it = this->lEspacioLibre.begin(); it != this->lEspacioLibre.end(); ++it){
		this->serInator.serializar(arr, *it);
	}
	return this->serInator.getBufferSize();
}


void CabeceraListaInvertida::deSerialize(char* arr){
	this->serInator.reset();

	this->serInator.desSerializar(arr, this->cantBloques);

	unsigned int cantElementos = 0;
	this->serInator.desSerializar(arr, cantElementos);

	// XXX: Se des-activo todo el control de espacio libre
	return;

/* Como no guardo los elementos para evitar problemas con el tamaño
 * del bloque no necesito, ni puedo, recuperarlos
 */

	for (unsigned int i = 0; i < cantElementos; ++i){
		char elem = 0;
		this->serInator.desSerializar(arr, elem);

		this->lEspacioLibre.push_back(elem);
	}
}


